/*
 * Copyright 2024-2025 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.cloud.ai.dashscope.video;

import com.alibaba.cloud.ai.dashscope.api.DashScopeVideoApi;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * DashScope Video Generation Options.
 *
 * @author dashscope
 * @author yuluo
 * @since 1.0.0.3
 */

public class DashScopeVideoOptions implements VideoOptions {

	/**
	 * Default video model.
	 */
	public static final String DEFAULT_MODEL = DashScopeVideoApi.VideoModel.WANX2_1_T2V_TURBO.getValue();

	@JsonProperty("model")
	private String model;

	@JsonProperty("img_url")
	private String imageUrl;

	@JsonProperty("prompt")
	private String prompt;

	/**
	 * The size parameter should be set directly to the specific value of the target
	 * resolution (such as 1280720), rather than the aspect ratio (such as 1:1) or the
	 * resolution gear name (such as 480P or 720P).
	 */
	@JsonProperty("size")
	private String size;

	/**
	 * The video generation time is in seconds. The current parameter value is fixed to 5
	 * and does not support modification. The model will always generate 5-second videos.
	 */
	@JsonProperty("duration")
	private Integer duration = 5;

	@JsonProperty("prompt_extend")
	private Boolean promptExtend;

	@JsonProperty("resolution")
	private String resolution;

	/**
	 * Random number seeds are used to control the randomness of the content generated by
	 * the model. The value range is [0, 2147483647].
	 */
	private Long seed;

	/**
	 * Reverse prompt words are used to describe content that you do not want to see in
	 * the video screen, and can limit the video screen.
	 */
	@JsonProperty("negative_prompt")
	private String negativePrompt;

	@JsonProperty("template")
	private DashScopeVideoApi.VideoTemplate template;

	@JsonProperty("first_frame_url")
	private String firstFrameUrl;

	@JsonProperty("last_frame_url")
	private String lastFrameUrl;

	public DashScopeVideoOptions(String imageUrl, Long seed, String prompt, String firstFrameUrl, String lastFrameUrl,
			String resolution, String model, String size, Boolean promptExtend, String negativePrompt,
			DashScopeVideoApi.VideoTemplate template) {

		this.imageUrl = imageUrl;
		this.prompt = prompt;
		this.firstFrameUrl = firstFrameUrl;
		this.lastFrameUrl = lastFrameUrl;
		this.resolution = resolution;
		this.size = size;
		this.model = model;
		this.promptExtend = promptExtend;
		this.negativePrompt = negativePrompt;
		this.seed = seed;
		this.template = template;
	}

	@Override
	public String getModel() {
		return this.model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public String getImageUrl() {
		return imageUrl;
	}

	public void setImageUrl(String imageUrl) {
		this.imageUrl = imageUrl;
	}

	public String getSize() {
		return this.size;
	}

	public void setSize(String size) {
		this.size = size;
	}

	public Integer getDuration() {
		return this.duration;
	}

	public void setDuration(Integer duration) {
		this.duration = duration;
	}

	public Boolean getPrompt() {
		return this.promptExtend;
	}

	public void setPrompt(Boolean promptExtend) {
		this.promptExtend = promptExtend;
	}

	public Long getSeed() {
		return this.seed;
	}

	public void setSeed(Long seed) {
		this.seed = seed;
	}

	public String getNegativePrompt() {
		return this.negativePrompt;
	}

	public void setNegativePrompt(String negativePrompt) {
		this.negativePrompt = negativePrompt;
	}

	public DashScopeVideoApi.VideoTemplate getTemplate() {
		return this.template;
	}

	public void setTemplate(DashScopeVideoApi.VideoTemplate template) {
		this.template = template;
	}

	public void setPrompt(String prompt) {
		this.prompt = prompt;
	}

	public Boolean getPromptExtend() {
		return promptExtend;
	}

	public void setPromptExtend(Boolean promptExtend) {
		this.promptExtend = promptExtend;
	}

	public String getResolution() {
		return resolution;
	}

	public void setResolution(String resolution) {
		this.resolution = resolution;
	}

	public String getFirstFrameUrl() {
		return firstFrameUrl;
	}

	public void setFirstFrameUrl(String firstFrameUrl) {
		this.firstFrameUrl = firstFrameUrl;
	}

	public String getLastFrameUrl() {
		return lastFrameUrl;
	}

	public void setLastFrameUrl(String lastFrameUrl) {
		this.lastFrameUrl = lastFrameUrl;
	}

	/**
	 * Builder for DashScopeVideoOptions.
	 */
	public static Builder builder() {
		return new Builder();
	}

	@Override
	public String toString() {

		return "DashScopeVideoOptions{" + "model='" + model + '\'' + ", imageUrl='" + imageUrl + '\'' + ", prompt='"
				+ prompt + '\'' + ", size='" + size + '\'' + ", duration=" + duration + ", promptExtend=" + promptExtend
				+ ", resolution='" + resolution + '\'' + ", seed=" + seed + ", negativePrompt='" + negativePrompt + '\''
				+ ", template=" + template + ", firstFrameUrl='" + firstFrameUrl + '\'' + ", lastFrameUrl='"
				+ lastFrameUrl + '\'' + '}';
	}

	/**
	 * Builder for DashScopeVideoOptions.
	 */
	public static class Builder {

		private String model = DEFAULT_MODEL;

		private String size = "832*480";

		private String prompt;

		private String imageUrl;

		private Integer duration = 5;

		private Boolean promptExtend = false;

		private Long seed;

		private String negativePrompt;

		private String resolution;

		private String firstFrameUrl;

		private String lastFrameUrl;

		private DashScopeVideoApi.VideoTemplate template;

		public Builder() {
		}

		public Builder prompt(String prompt) {
			this.prompt = prompt;
			return this;
		}

		public Builder imageUrl(String imageUrl) {
			this.imageUrl = imageUrl;
			return this;
		}

		public Builder firstFrameUrl(String firstFrameUrl) {
			this.firstFrameUrl = firstFrameUrl;
			return this;
		}

		public Builder lastFrameUrl(String lastFrameUrl) {
			this.lastFrameUrl = lastFrameUrl;
			return this;
		}

		public Builder resolution(String resolution) {
			this.resolution = resolution;
			return this;
		}

		public Builder model(String model) {
			this.model = model;
			return this;
		}

		public Builder size(String size) {
			this.size = size;
			return this;
		}

		public Builder duration(Integer duration) {
			this.duration = duration;
			return this;
		}

		public Builder promptExtend(Boolean promptExtend) {
			this.promptExtend = promptExtend;
			return this;
		}

		public Builder seed(Long seed) {
			this.seed = seed;
			return this;
		}

		public Builder negativePrompt(String negativePrompt) {
			this.negativePrompt = negativePrompt;
			return this;
		}

		public Builder template(DashScopeVideoApi.VideoTemplate template) {
			this.template = template;
			return this;
		}

		public DashScopeVideoOptions build() {

			return new DashScopeVideoOptions(this.imageUrl, this.seed, this.prompt, this.firstFrameUrl,
					this.lastFrameUrl, this.resolution, this.model, this.size, this.promptExtend, this.negativePrompt,
					this.template);
		}

	}

}
